package com.example.demo.controller;

import com.example.demo.entity.Photo;
import com.example.demo.service.PhotoService;
import com.example.demo.utils.ImgRotate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.UUID;

/**
 * (Photo)表控制层
 *
 * @author makejava
 * @since 2021-01-10 17:36:54
 */
@RestController
@RequestMapping("photo")
public class PhotoController {
    /**
     * 服务对象
     */
    @Resource
    private PhotoService photoService;

    @Value("${file.path}")
    private String filePath;

    @Value("${file.url}")
    private String fileUrl;

    @Autowired
    private CacheManager cacheManager;

    /**
     * 图片
     *
     * @param file
     * @return
     */
    @RequestMapping("upload")
    public ResponseEntity upload(MultipartFile file) {
        try {
            String originalFilename = file.getOriginalFilename();
            long size = file.getSize();
            Photo photo = new Photo();
            photo.setOriginName(originalFilename);
            photo.setSize((int) size);
            String newFileName = getUuidFileName(originalFilename);
            photo.setFileName(newFileName);
            photo.setRealPath(filePath + newFileName);
            photo.setUrl(fileUrl + newFileName);
            photo.setCreateTime(new Date());
            photoService.insert(photo);
            file.transferTo(new File(photo.getRealPath()));
            return ResponseEntity.ok().body(photo);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseEntity.badRequest().body(HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @GetMapping("{id}")
    public ResponseEntity findById(@PathVariable Integer id, String operate) throws Exception {
        Photo photo = photoService.queryById(id);
        Photo newPhoto = new Photo();
        switch (operate) {
            case "R90":
                //TODO
                newPhoto.setOriginName(photo.getFileName());
                String newFileName = getUuidFileName(photo.getOriginName());
                newPhoto.setFileName(newFileName);
                newPhoto.setRealPath(filePath + newFileName);
                newPhoto.setUrl(fileUrl + newFileName);
                newPhoto.setCreateTime(new Date());
                photoService.insert(newPhoto);
                ImgRotate.rotateImage(new File(photo.getRealPath()), new File(newPhoto.getRealPath()), 90);
                break;
            case "R180":
                //TODO
                break;
            case "R270":
                //TODO
                break;
        }

        return ResponseEntity.ok().body(newPhoto);
    }


    @GetMapping("/download")
    public void download(int pid, HttpServletResponse response) throws IOException {
        Photo photo = photoService.queryById(pid);
        File file = new File(photo.getRealPath());
        if (file.exists()) {
            //设置MIME类型
            response.setContentType("application/octet-stream");
            //或者为response.setContentType("application/x-msdownload");
            //设置头信息,设置文件下载时的默认文件名，同时解决中文名乱码问题
            response.addHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(photo.getFileName(), "UTF-8"));
            InputStream inputStream = new FileInputStream(file);
            ServletOutputStream outputStream = response.getOutputStream();
            byte[] bs = new byte[1024];
            while ((inputStream.read(bs) > 0)) {
                outputStream.write(bs);
            }
            outputStream.close();
            inputStream.close();
        }
    }


    /**
     * 目录分离算法:由此算法可以得到8级目录,每一级目录中最多有16个子目录,所以此算法最大可计算出42.9亿多个存储路径.
     * 由唯一文件名计算出一个存储路径,可以有效避免在一个目录中存储太多的文件.
     */
    public static String getRandomDirectory(String fileName) {
        int dir;
        int hashcode = fileName.hashCode();
        StringBuilder path = new StringBuilder();
        for (int i = 0; i < 32; i += 4) {
            dir = hashcode & 0xf;
            hashcode = hashcode >> 4;
            // 字符串拼接
            path.append(File.separator + dir);
        }
        return path.toString();
    }

    /**
     * 根据文件名,获取唯一的UUID文件名
     *
     * @param fileName
     * @return
     */
    public static String getUuidFileName(String fileName) {
        int index = fileName.lastIndexOf(".");
        if (index != -1) {
            return UUID.randomUUID().toString().replace("-", "") + fileName.substring(index);
        } else {
            throw new RuntimeException("文件名称有误");
        }

    }


}